package com.cac.demo.service.MsSslShelves;

import com.cac.demo.dao.msConsole.MsConsoleDao;
import com.cac.demo.newCode.sorting.entity.MsAssginWorkbintoolRel;
import com.cac.demo.newCode.sorting.service.IMsAssginWorkbintoolRelService;
import com.cac.demo.newCode.sorting.service.SortingTaskService;
import com.cac.demo.service.outStoreRoom.OutStoreroomService;
import com.cac.demo.util.*;
import com.cac.demo.entity.GkLog.MsGkLogDTO;
import com.cac.demo.entity.MsSslShelves.MsSslShelvesDTO;
import com.cac.demo.dao.gkLog.MsAddressDao;
import com.cac.demo.dao.gkLog.MsGkLogDao;
import com.cac.demo.dao.MsSslShelves.MsSslShelvesDao;
import com.cac.demo.controller.msSslShelves.MsSslShelvesRest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.cac.demo.util.adapter.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import net.logstash.logback.encoder.org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class MsSslShelvesService extends R {
    @Autowired
    private MsSslShelvesDao msSslShelvesDao;
    @Autowired
    private MsGkLogDao msGkLogDao;
    @Autowired
    private MsAddressDao msAddressDao;
    @Autowired
    private MsConsoleDao msConsoleDao;
    @Autowired
    private Environment environment;
    @Autowired
    private OutStoreroomService outStoreroomService;
    @Resource
    private SortingTaskService sortingTaskService;

    @Autowired
    private CreateCommonLog createCommonLog;
    @Value("${pathProperty.isTest}")
    private boolean isTest;
    @Autowired
    private WcsLogRecord wcsLogRecord;

    /**
     * 更新回库时获得具体储位时间
     */
    @Transactional
    public void updateLog(Map map) {
        try {
            msGkLogDao.updateMsGKLog(map, map.toString());
        } catch (Exception e) {
            log.info(ExceptionToStirng.getExceptionToString(e));
            throw new DaoException(e.getMessage());
        }
    }


    /**
     * 回库时获取巷道后更新获取巷道时间
     */
    @Transactional
    public void updateBackLog(Map map) {
        try {
            msGkLogDao.updateBackLog(map, map.toString());
        } catch (Exception e) {
            e.printStackTrace();
            log.info(ExceptionToStirng.getExceptionToString(e));
        }
    }

    /**
     * 创建移库时,出库任务记录操作日志---加入父亲任务id
     */
    @Transactional
    public void updateLogForMove(Map map) {
        log.info("移库时更新日志操作记录，为子任务加入父任务id" + map.toString());
        try {
            msGkLogDao.updateLogForMove(map);
        } catch (Exception e) {
            e.printStackTrace();
            log.info(ExceptionToStirng.getExceptionToString(e));
            throw new DaoException(e.getMessage());
        }
    }

    /**
     * 回库时查询任务操作日志id
     */
    public HashMap selectWmsTaskId(String palletCode) {
        return msGkLogDao.selectWmsTaskId(palletCode);
    }

    /**
     * 查询储位信息
     *
     * @param
     * @return
     */
    @Transactional
    public String getSpaceCode(String startCode, String palletCode, int palletHeight, Long wmsTaskId) {
        String result = null;
        try {
            //获取分配的货位
            String sqlResult = msSslShelvesDao.getSpaceCode(palletCode, startCode, palletHeight);
            if (sqlResult == null) {
                //未获取货位
                result = "400";
            } else {
                //获取到分配货位后，更新立体库货位信息
                int udpateCount = msSslShelvesDao.updateShelvesCode(sqlResult, palletCode);
                //结果返回接收，货位编码
                result = sqlResult;
                //
                if (udpateCount == 0) {
                    result = "400";
                }
            }
        } catch (Exception e) {
            log.info(ExceptionToStirng.getExceptionToString(e));
            e.printStackTrace();
        } finally {
            return result;
        }
    }

    /**
     * 堆垛机调用接口时，根据托盘号获取扫描位分配给该托盘的具体货位
     *
     * @param palletCode
     * @return
     */
    public String getCorrespondingShelves(String palletCode) {
        String result = null;
        try {
            //获取分配的货位
            String sqlResult = msSslShelvesDao.getCorrespondingShelves(palletCode);
            if (sqlResult == null) {
                //未获取货位
                result = "400";
            } else {
                //结果返回接收，货位编码
                result = sqlResult;
            }
        } catch (Exception e) {
            log.info(ExceptionToStirng.getExceptionToString(e));
            e.printStackTrace();
        } finally {
            return result;
        }
    }

    /**
     * 查询巷道信息
     *
     * @param
     * @return
     */
    public String getRoadWay(int location, int count) {
        String result = null;
        try {
            result = msSslShelvesDao.getRoadWay(location, count);
        } catch (Exception e) {
            log.info(ExceptionToStirng.getExceptionToString(e));
            e.printStackTrace();
            result = "400";
        } finally {
            return result;
        }
    }

    /**
     * 直接在扫描位获取具体货位，根据具体货位获取巷道
     */
    @Transactional
    public HashMap getShelves(int location, int count, String palletHeight, String palletCode, Object wmsTaskId, Object startCode) {
        HashMap result = new HashMap<>();
        try {
            //防止wcs多次调用，首先判断该任务id是否已经分配过货位
            HashMap exist = msGkLogDao.isGetLocation(wmsTaskId);
            if (exist == null) {//等于空，证明没有分配过货位
                //判断是否有货位给货物装货
                if (msSslShelvesDao.getShelves(location, count, palletHeight, startCode, isTest) != null) {
                    //存在即进行分配 货位
                    if (isTest) {
                        result = msSslShelvesDao.getShelves(location, count, palletHeight, startCode, isTest);
                    } else {
                        result = msSslShelvesDao.getShelves(location, count, palletHeight, startCode, isTest);
                    }
                    msSslShelvesDao.updateShelvesCode((String) result.get("SHELVES_CODE"), palletCode);
                    result.put("wmsTaskId", wmsTaskId);
                    updateBackLog(result);
                    result.put("retCode", "200");
                    log.info("result++++++++++++" + result);
                } else {
                    //返回没有合适货位
                    result.put("taskOn", "1");
                    log.info("result++++++++++++" + result);
                }
            } else {//分配过任务
                log.info("分配过任务！++++++++++++");
                result.put("ROW_NO", exist.get("roadway"));
                result.put("SHELVES_CODE", exist.get("endCode"));
                result.put("retCode", "200");
            }
        } catch (Exception e) {
            log.info(ExceptionToStirng.getExceptionToString(e));
            e.printStackTrace();
            result.put("retCode", "201");
        } finally {
            return result;
        }
    }


    /**
     * 出库查询移库信息
     *
     * @param
     * @return "200" 需要移库  "201" 不需要移库  "500"当前位置无法出库
     */
    public ResponseMsg isNeedMove(Map map) {
        ResponseMsg responseMsg = new ResponseMsg();
        HashMap tmpHashMap = null;
        try {
            //查询当前出库位置的外面位置是否有状态为3的占位信息
            tmpHashMap = msSslShelvesDao.isNeedMove(map);
            if (!Objects.isNull(tmpHashMap)) {//判断是否双深位
                String status = tmpHashMap.get("STATUS").toString();
                if ("3".equals(status)) {//状态为3，
                    if ("".equals(tmpHashMap.get("PALLET_CODE")) || tmpHashMap.get("PALLET_CODE") == null) {
                        responseMsg.setRetCode("500").setMessage("请查询当前位置的外面位置数据是否异常！");
                    } else {
                        //未完成任务集合
                        List<HashMap> list = this.isFinishTask(tmpHashMap);
                        HashMap tasks = new HashMap();
                        if (list.size() == 0) {
                            responseMsg.setRetCode("200");
                        } else {
                            // TODO: 2023/6/5 查询wcs任务状态
                            tasks = list.get(0);
                            if (Objects.isNull(tasks.get("ORDER_TIME"))) {//判断是否有已创建未下发的出库任务
                                //有未完成任务，但是未下发,可以直接下发
                                String rsl = this.doTask(tasks);
                            } else {
                                //未完成任务已经下发（可能为出库任务或者移库任务）
                                responseMsg.setRetCode("500").setMessage("请查询当前位置的外面位置是否有未完成任务！");
                            }
                        }
                    }
                } else if ("2".equals(status)) {

                    // TODO: 2023/6/5 查询wcs任务状态，任务可能为未完成的入库任务，或者移库任务，根据实际情况可在此处直接完成任务

                    responseMsg.setRetCode("500").setMessage("请查询当前位置的外面位置是否有未完成任务！");
                } else {//外面空闲不需要移库
                    responseMsg.setRetCode("201");
                }
            } else {
                //当前位置不是双深位或者是双深位外面位置，不需要移库
                responseMsg.setRetCode("201");
            }
            responseMsg.setResponseBody(tmpHashMap);
        } catch (
                Exception e) {
            log.info(ExceptionToStirng.getExceptionToString(e));
            e.printStackTrace();
        } finally {
            return responseMsg;

        }

    }

    public List<HashMap> isFinishTask(Map map) {
        return msSslShelvesDao.isFinishTask(map);
    }

    //判断移库位是否有未完成任务
    public List<HashMap> searchDependShelvesPallet(Map map) {
        return msSslShelvesDao.searchDependShelvesPallet(map);
    }


    /**
     * 获取双深位内部货位绑定的外部阻挡货位
     *
     * @param
     * @return
     */
    public String getDependLocationPalletCode(String DependLocation) {
        try {
            String result = msSslShelvesDao.getDependLocation(DependLocation);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            log.info(ExceptionToStirng.getExceptionToString(e));
            return R.failed("400").toString();
        }
    }

    /**
     * 获取双深位内部货位绑定的外部阻挡货位
     *
     * @param
     * @return
     */
    public synchronized String getAvailableLocation(Map map, String list) {
        String result = null;
        try {
            result = msSslShelvesDao.getAvailableLocation(map, list);
        } catch (Exception e) {
            log.info(ExceptionToStirng.getExceptionToString(e));
            e.printStackTrace();
        } finally {
            return result;
        }
    }

    /**
     * 检查储位是否有遮挡
     *
     * @param
     * @return
     */
    public String checkSpace(String spaceCode) {
        try {
            return msSslShelvesDao.checkSpace(spaceCode);
        } catch (Exception e) {
            log.info(ExceptionToStirng.getExceptionToString(e));
            throw new DaoException(e.getMessage());
        }
    }

    @Transactional
    public String doTask(Map map) {
        PrintWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        MsGkLogDTO msGkLogDTO = new MsGkLogDTO();
        JSONObject resutJSon = new JSONObject();
        Map keyMap = GetAuthKey.getKey();
        resutJSon.put("command", map.get("command"));
        resutJSon.put("taskType", map.get("taskType"));
        resutJSon.put("startCode", map.get("startCode"));
        resutJSon.put("wmsTaskId", map.get("wmsTaskId"));
        resutJSon.put("palletCode", map.get("palletCode"));
        resutJSon.put("roadway", map.get("roadway"));
        resutJSon.put("endCode", map.get("endCode"));
        resutJSon.put("appId", keyMap.get("appId"));
        resutJSon.put("appCode", keyMap.get("appCode"));
        resutJSon.put("timeStamp", keyMap.get("timeStamp"));
        resutJSon.put("appKey", keyMap.get("appKey"));
        resutJSon.put("sysKey", keyMap.get("sysKey"));
        String params = resutJSon.toString();
        log.info("传参++++++++++" + map.toString());
        String urlPath = msAddressDao.findPath("WCS");
        log.info("开始调用wcs任务" + resutJSon.toString());
        Map extendMap = new HashMap();
        String id = ComUtil.getId();
        long starttimeex = System.currentTimeMillis();
        try {
            //2023-05-26 yebo 添加日志记录
            Map lMap = JSON.parseObject(resutJSon.toJSONString(), Map.class);
            extendMap.put("callUrl", urlPath);
            extendMap.put("logType", "call-dotask");
            extendMap.put("wcsResult", result.toString());
            extendMap.put("ID", id);
            extendMap.put("preWmsTaskId", map.get("preWmsTaskId"));
            wcsLogRecord.saveCallBackLog(lMap, extendMap, false, map.get("wmsTaskId").toString());
            String debugModel = environment.getProperty("pathProperty.deBug");
            long starttime = System.currentTimeMillis();
            if ("false".equals(debugModel)) {
                String urlNameString = urlPath + "/api/wcs/api/chengfei/task";
                log.info(urlNameString + "-------------------------urlNameString");
//            String urlNameString = "https://60j083o206.goho.co:8088/MsSslShelvesRest/demoDotask";
                //log.info("sendPost - {}", urlNameString);
                URL realUrl = new URL(urlNameString);
                URLConnection conn = realUrl.openConnection();
                conn.setRequestProperty("accept", "*/*");
                conn.setRequestProperty("connection", "Keep-Alive");
                conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
                conn.setRequestProperty("Accept-Charset", "utf-8");
                conn.setRequestProperty("content-type", "application/json");
                conn.setDoOutput(true);
                conn.setDoInput(true);
                out = new PrintWriter(conn.getOutputStream());
                out.print(params);
                out.flush();
                in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
                String line;
                while ((line = in.readLine()) != null) {
                    result.append(line);
                }
            }
            long endtime = System.currentTimeMillis();
            //打包注释
            log.info(result.toString());
//            //依靠日志实体参数，新增实体操作
//            log.info("根据下发任务，创建日志记录"+map.toString());
//            msGkLogDao.creatLog(map,map.toString());
            //更新下发任务时间
            msGkLogDao.updateOrderTime(map);
            msGkLogDao.putLogParam("wms-wcs下发任务,", map.toString(), map.get("wmsTaskId"), (String) map.get("startCode"));
            extendMap.put("dealTime", (endtime - starttime) + "ms");
            extendMap.put("wcsResult", result.toString());
            wcsLogRecord.updateDeatilLog(extendMap);
        } catch (Exception e) {
            log.info(ExceptionToStirng.getExceptionToString(e));
            e.printStackTrace();
            R.failed("400", e.getMessage());
            long endtime = System.currentTimeMillis();
            extendMap.put("dealTime", (endtime - starttimeex) + "ms");
            extendMap.put("wmsResult", "wms处理异常：【" + System.currentTimeMillis() + "】" + e.getMessage());
            wcsLogRecord.updateDeatilLog(extendMap);
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
                log.info(ex.getMessage());
            }

        }
        return result.toString();
    }

    /**
     * 出入库有遮挡时，调用
     *
     * @param map
     * @return
     */
    @Transactional
    public String doTaskByMove(Map map) {
        PrintWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        MsGkLogDTO msGkLogDTO = new MsGkLogDTO();
//        Long wmsTaskId = 178964251L;
        JSONObject resutJSon = new JSONObject();
        Map keyMap = GetAuthKey.getKey();
        resutJSon.put("command", map.get("COMMAND"));
        resutJSon.put("taskType", map.get("TASK_TYPE"));
        resutJSon.put("startCode", map.get("START_CODE"));
        resutJSon.put("wmsTaskId", map.get("WMS_TASK_ID"));
        resutJSon.put("palletCode", map.get("PALLET_CODE"));
        resutJSon.put("roadway", map.get("ROADWAY"));
        resutJSon.put("endCode", map.get("END_CODE"));
        resutJSon.put("appId", keyMap.get("appId"));
        resutJSon.put("appCode", keyMap.get("appCode"));
        resutJSon.put("timeStamp", keyMap.get("timeStamp"));
        resutJSon.put("appKey", keyMap.get("appKey"));
        resutJSon.put("sysKey", keyMap.get("sysKey"));
        String params = resutJSon.toString();
        log.info("传参++++++++++" + map.toString());
        log.info("移库回调出库指令+++++++++++++++++++++++++++++++++" + resutJSon.toString());
        String urlPath = msAddressDao.findPath("WCS");
        Map extendMap = new HashMap();
        String id = ComUtil.getId();
        long starttimeex = System.currentTimeMillis();
        try {
            String debugModel = environment.getProperty("pathProperty.deBug");
            //2023-05-30 yebo 添加日志记录
            Map lMap = JSON.parseObject(resutJSon.toJSONString(), Map.class);
            extendMap.put("callUrl", urlPath);
            extendMap.put("logType", "call-move");
            extendMap.put("wcsResult", result.toString());
            extendMap.put("ID", id);
            wcsLogRecord.saveCallBackLog(lMap, extendMap, false, map.get("wmsTaskId").toString());
            long starttime = System.currentTimeMillis();
            if ("false".equals(debugModel)) {
                String urlNameString = urlPath + "/api/wcs/api/chengfei/task";
                log.info(urlNameString + "-------------------------urlNameString");
//            String urlNameString = "https://60j083o206.goho.co:8088/MsSslShelvesRest/demoDotask";
                //log.info("sendPost - {}", urlNameString);
                URL realUrl = new URL(urlNameString);
                URLConnection conn = realUrl.openConnection();
                conn.setRequestProperty("accept", "*/*");
                conn.setRequestProperty("connection", "Keep-Alive");
                conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
                conn.setRequestProperty("Accept-Charset", "utf-8");
                conn.setRequestProperty("content-type", "application/json");
                conn.setDoOutput(true);
                conn.setDoInput(true);
                out = new PrintWriter(conn.getOutputStream());
                out.print(params);
                out.flush();
                in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
                String line;
                while ((line = in.readLine()) != null) {
                    result.append(line);
                }
            }
            long endtime = System.currentTimeMillis();
            log.info("wms移库完成后下方wcs出库指令，wcs返回结果+++++++++++++++++++++++++++++++++" + result.toString());
            //更新下发任务时间
            map.put("wmsTaskId", map.get("WMS_TASK_ID"));
            msGkLogDao.updateOrderTime(map);
            msGkLogDao.putLogParam("双深位移库指令完成后自动触发出库任务,", map.toString(), map.get("wmsTaskId"), (String) map.get("START_CODE"));
            //log.info("recv - {}", result);
            extendMap.put("dealTime", (endtime - starttime) + "ms");
            extendMap.put("wcsResult", result.toString());
            wcsLogRecord.updateDeatilLog(extendMap);
        } catch (Exception e) {
            log.info(ExceptionToStirng.getExceptionToString(e));
            e.printStackTrace();
            R.failed("400", e.getMessage());
            long endtime = System.currentTimeMillis();
            extendMap.put("dealTime", (endtime - starttimeex) + "ms");
            extendMap.put("wmsResult", "wms处理异常：【" + System.currentTimeMillis() + "】" + e.getMessage());
            wcsLogRecord.updateDeatilLog(extendMap);
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                log.info(ex.getMessage());
            }

        }
        return result.toString();
    }

    /**
     * 2.4 接收wcs反馈信息
     *
     * @param
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int callBack(Map map) {
        long timestamp = System.currentTimeMillis();
        //wcs回调wms，任务参数
        String param = JSON.toJSONString(map.get("command"));
        Integer command = JSON.parseObject(param, Integer.class);
        //wms任务ID
        String paramWmsTaskId = JSON.toJSONString(map.get("wmsTaskId"));
        Long wmsTaskId = JSON.parseObject(paramWmsTaskId, Long.class);
        log.info("当前时间戳【" + timestamp + "】wmsTaskId:" + wmsTaskId);
        //根据任务id号，查询日志表任务信息
        HashMap logData = msGkLogDao.selectLogData(wmsTaskId);
        String taskType = (String) logData.get("TASK_TYPE");
        String logCommand = (String) logData.get("COMMAND");
        Integer result = null;
        try {
            if (command == 1) {
                result = msSslShelvesDao.taskStartCallBack(map, map.toString());
            } else if (command == 2) {
                //如果完成的任务是入库任务，维护立体库信息表
                if (logCommand != null && logCommand.equals("5")) {
                    log.info("入库任务完成，更新立体库ShelveCode：回调参数【" + timestamp + "】：" + map.toString() +
                            ";修改立体库参数：" + logData.toString());
                    msSslShelvesDao.successInputShelvesCode(logData);
                    //待下发任务容器
                    HashMap callTask = new HashMap();
                    //判断是否存在分拣位，需要该盘子。查询出结束位置endCode，提供给接口使用。查询出的任务wmsTaskId，用于修改起始位置
                    List<HashMap> callTasks = msGkLogDao.unCallSortTask(logData);
                    //是否存在分拣位需要当前入库盘子
                    if (!callTasks.isEmpty()) {
                        //存在，更新任务起始位置后调用下发任务方法。
                        //将任务参数放入容器中
                        callTask = callTasks.get(0);
                        //将入库任务的结束位置——货架位置，当做需要修改的出库任务的起始位置
                        callTask.put("startCode", logData.get("END_CODE"));
                        //更新任务日志表中的起始位置
                        msGkLogDao.updateStartCodeByTaskId(callTask);
                        //容器存入，操作标识符
                        callTask.put("func", "sort");
                        createCommonLog.callWCSInterface(callTask);
                    } else {
                        //不存在不操作。
                        log.info("当前货物不需要进行二次操作！");
                    }
                } else {//2023-06-12 出库情况如果没有改到货架，则改货架信息
                    msSslShelvesDao.issueUpdateShelvesCode(logData);
                    log.info("=====出库更改货架信息======" + wmsTaskId);
                }
                //如果完成的任务是移库任务，维护立体库信息表
                if (taskType != null && taskType.equals("3") && logData.get("ROADWAY") != null) {
                    log.info("移库任务完成,当前时间戳【" + timestamp + "】,更新立体库ShelveCode,回调参数：" + map.toString() +
                            ";修改立体库参数：" + logData.toString());
                    //将旧货物是否为空箱状态，跟随参数，方便更新新货位时一并添加
                    logData.putAll(msSslShelvesDao.searchIsEmputy(logData));
                    //更新旧货位，托盘编码设置为空，货位状态更改为空闲。
                    msSslShelvesDao.successMoveShelvesCodeChangeFirst(logData);
                    //更新新货位，添加托盘编码，货位状态更改为已占用。
                    msSslShelvesDao.successMoveShelvesCodeChangeSeconde(logData);

                    //移库任务完成，清理占用信息
                    MsSslShelvesRest.moveLocations.remove(logData.get("END_CODE"));
                    log.info("当前分配位置占用:" + MsSslShelvesRest.moveLocations.toString());
                }
                msSslShelvesDao.taskSuccessCallBack(map, map.toString());
                //查询子任务ID
                Map wmsTaskMap = msGkLogDao.selectWmsTaskIdByParentTaskId(wmsTaskId);
                if (wmsTaskMap != null) {
                    //根据父任务id查询出子任务id，执行子任务id任务
                    doTaskByMove(wmsTaskMap);
                }
                result = 1;
            } else if (command == 4) {
                //堆垛机下架完成
                //如果完成的任务是出库任务，维护立体库信息表
                if (taskType != null && taskType.equals("2")) {
                    log.info("出库任务完成，当前时间戳【" + timestamp + "】更新立体库ShelveCode：回调参数：" + map.toString() +
                            ";修改立体库参数：" + logData.toString());
                    msSslShelvesDao.issueUpdateShelvesCode(logData);
                }
                result = 1;
            } else if (command == 5) {
                //wcs1066扫描位出库前回调
                //根据查询出的工作包id判断是否为配送出库任务,获取配送优先级
                HashMap callPriority = msGkLogDao.isOutboundDelivery(wmsTaskId);
                //配送任务进过1066位
                if (callPriority != null && !callPriority.isEmpty()) {
                    log.info("================【工作包经过1066位】===================" + wmsTaskId);
                    //工作包经过1066位时，更新日志表信息
                    msGkLogDao.updatePassPallet(wmsTaskId);
                    //判断该优先级任务是否存在未经过1066的配送任务
                    Integer sqlNum = msGkLogDao.isNotPassPallet(callPriority);
                    if (sqlNum != 0) {
                        //任然存在未经过1066的配送任务
                        result = 3;
                    } else {
                        //拼装任务
                        HashMap callWcsData = new HashMap();
                        callWcsData.put("func", "agv");
                        //最后一个配送任务，调用封装下发wcs任务接口，下发下一个优先级任务
                        createCommonLog.callWCSInterface(callWcsData);
                        result = 2;
                    }
                } else {
                    //其他操作经过1066位
                    //根据wmsTaskId任务号，查询具体任务数据
                    HashMap callWcsTask = msGkLogDao.searchCallControlData(wmsTaskId);
                    //工作包经过1066位时，更新日志表信息
                    msGkLogDao.updatePassPallet(wmsTaskId);
                    log.info("1066回调：触发下一次分拣任务：");
                    callWcsTask.put("func", "sort");
                    if (callWcsTask.get("palletCode").toString().startsWith("1")) {
                        callWcsTask.put("boxType", "WORKBIN");
                    } else {
                        callWcsTask.put("boxType", "TOOL");
                    }

                    //yebo 处理下面箱子是一个箱子的情况 将紧挨的箱子更改为已经打到分拣台-----start  2023-11-03 yebo 注释该程序，已经用不上了，现阶段模式不会出现这种情况
                /*    List<HashMap> pallectCodes = msGkLogDao.queryRepeatGkLog(callWcsTask);
                    if (pallectCodes != null && pallectCodes.size() > 0) {
                        int curCallPriority = Integer.parseInt(callWcsTask.get("callPriority").toString());
                        log.info("【经过1066位--相同操作盘数量】:" + pallectCodes.size());
                        for (HashMap pallectCode : pallectCodes) {
                            curCallPriority++;
                            int tmp = Integer.parseInt(pallectCode.get("callPriority").toString());
                            if (tmp == curCallPriority) {//判断下一个箱子与当前经过1066点位的操作盘是不是同一个
                                log.info("当前操作盘与下一个操作盘相同，继续下一次循环");
                                msGkLogDao.updateRepeatGkLog(pallectCode);
                                continue;
                            }
                            log.info("当前操作盘与下一个操作盘不同，跳出循环,叫箱");
                            break;
                        }
                        //yebo 处理下面箱子是一个箱子的情况----------------end
                    }*/
                    log.info("【准备调用wcs叫下一哥托盘/箱子】" + callWcsTask.toString());
                    //经过1066位时，更新日志表信息-
                    msGkLogDao.updatePassPallet(wmsTaskId);
                    //分拣暂停
                    boolean pauseTask = sortingTaskService.getPauseTask();
                    if(pauseTask){
                        //调用封装接口,分拣操作下发命令，控制流量
                        createCommonLog.callWCSInterface(callWcsTask);

                        result = 4;
                    }
                }
            } else {
                msSslShelvesDao.taskFailCallBack(wmsTaskId, command);
                result = 5;
            }
            String sqlParam = "WCS-WMS回调接口,操作类型:" + command;
            msGkLogDao.putLogParam(sqlParam, map.toString(), wmsTaskId, "WCS任务回调位");
        } catch (Exception e) {
            e.printStackTrace();
            log.info(ExceptionToStirng.getExceptionToString(e));
            result = 0;
        } finally {
            log.info("=======MssslShelvesService.callBack===执行最后一步打印 finally==result【" + result + "】==" + wmsTaskId);
            return result;
        }
    }


    /**
     * 返回起始地址
     *
     * @param IP
     * @return
     */
    public String findStartCode(String IP, String boxType) {
        String result = null;
        try {
            result = msConsoleDao.findStartCode(IP, boxType);
        } catch (Exception e) {
            log.info(ExceptionToStirng.getExceptionToString(e));
            e.printStackTrace();
        } finally {
            return result;
        }
    }

    public int searchPalletIsOnShelves(String palletCode) {
        return msSslShelvesDao.searchPalletIsOnShelves(palletCode);
    }

    /**
     * 叫箱完成后，对立体库进行信息维护
     *
     * @param shelvesCodes
     * @return
     */
    @Transactional
    public String updateSslShelvesByShelvesCode(List<String> shelvesCodes) {
        try {
            for (String shelvesCode : shelvesCodes
            ) {
                msSslShelvesDao.updateSslShelvesByShelvesCode(shelvesCode);
            }
        } catch (Exception e) {
            log.info(ExceptionToStirng.getExceptionToString(e));
            return e.toString();
        }
        return "200";
    }


    /**
     * 批量新增数据
     *
     * @param msSslShelvesDTOS
     * @return
     */
    @Transactional
    public int batchInsertMsSslShelvesDTO(List<MsSslShelvesDTO> msSslShelvesDTOS) {
        List<MsSslShelvesDTO> beanList = new ArrayList<>();
        for (MsSslShelvesDTO msSslShelvesDTO : msSslShelvesDTOS
        ) {
            msSslShelvesDTO.setMsSslShelvesId(ComUtil.getId());
            beanList.add(msSslShelvesDTO);
        }
        try {
            return msSslShelvesDao.batchInsertMsSslShelvesDTO(beanList);
        } catch (Exception e) {
            log.info(ExceptionToStirng.getExceptionToString(e));
            throw new DaoException(e.getMessage(), e);
        }


    }

    /**
     * 根据物料箱编码查询数据
     *
     * @param id
     * @return
     */
    @Transactional
    public MsSslShelvesDTO searchMsSslShelvesById(String id) {
        try {
            MsSslShelvesDTO msSslShelvesDTO = msSslShelvesDao.searchMsSslShelvesDTOById(id);
            return msSslShelvesDTO;
        } catch (Exception e) {
            log.info(ExceptionToStirng.getExceptionToString(e));
            throw new DaoException(e.getMessage(), e);
        }
    }

    /**
     * 修改数据
     *
     * @param map
     * @return
     */
    @Transactional
    public int updateMsSslShelves(HashMap map) {
        try {
            int count = msSslShelvesDao.updateMssSslShelves(map);
            if (count == 0) {
                throw new DaoException("数据修改失败");
            }
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            throw new DaoException(e.getMessage(), e);
        }
    }

    /**
     * 批量修改数据
     *
     * @param doList
     * @return
     */
    @Transactional
    public int updateMsSslShelvesMany(List<HashMap> doList) {
        int count = 0;
        for (HashMap msSslShelvesDTO : doList
        ) {
            updateMsSslShelves(msSslShelvesDTO);
            count++;
        }
        return count;
    }

    /**
     * 内部方法，修改新数据到旧数据中
     *
     * @param msSslShelvesDTO
     * @return
     */
    private MsSslShelvesDTO getUpdateDTO(HashMap msSslShelvesDTO) {
        MsSslShelvesDTO oldDTO = msSslShelvesDao.searchMsSslShelvesDTOById((String) msSslShelvesDTO.get("shelvesCode"));
        if (oldDTO == null) {
            throw new DaoException("数据不存在");
        }
        PojoUtil.copyProperties(oldDTO, msSslShelvesDTO, true);
        return oldDTO;
    }

    /**
     * 根据主键id删除数据
     *
     * @param sslIds
     * @return
     */
    @Transactional
    public Map deleteMsSslShelvesDTO(List<String> sslIds) {
        int sucCount = 0;
        int falCount = 0;
        Map result = new HashMap();
        List<String> falId = new ArrayList<>();
        for (String sslId : sslIds
        ) {
            if (StringUtils.isEmpty(sslId)) {
                falCount++;
                falId.add(sslId + "数据不存在，删除失败！");
            }
            try {
                MsSslShelvesDTO msSslShelvesDTO = msSslShelvesDao.searchMsSslShelvesDTOById(sslId);
                if (msSslShelvesDTO == null) {
                    falCount++;
                    falId.add(sslId + "数据为空，删除失败");
                } else {
                    msSslShelvesDao.deleteMsSslShelvesDTO(sslId);
                    sucCount++;
                }
            } catch (Exception e) {
                log.info(ExceptionToStirng.getExceptionToString(e));
                throw new DaoException(e.getMessage(), e);
            }
        }
        result.put("sucCount", sucCount);
        result.put("falCount", falCount);
        result.put("falReson", falId);
        return result;
    }

    /**
     * 根据条件查询数据
     *
     * @param
     * @return
     */
    public PageInfo searchMsSslShelvesDTOByParams(HashMap page, HashMap queryMap) {
        try {
            String testFlag = "false";
            com.github.pagehelper.PageHelper.startPage(Integer.parseInt(page.get("page").toString()),Integer.parseInt(page.get("rows").toString()));
            if(isTest){
                testFlag = "true";
            }
            return new PageInfo(msSslShelvesDao.searchMsSslShelvesByParams(queryMap,testFlag));
        } catch (Exception e) {
            e.printStackTrace();
            throw new DaoException(e.getMessage(), e);
        }
    }


    /**
     * 新增一条数据
     *
     * @param msSslShelvesDTO
     * @return
     */
    @Transactional
    public String insertMsSslShelvesDTO(MsSslShelvesDTO msSslShelvesDTO) {
        try {
            if (msSslShelvesDao.insertMsSslShelvesDTO(msSslShelvesDTO) != 0) {
                return "200";
            }
            return "400";
        } catch (Exception e) {
            log.info(ExceptionToStirng.getExceptionToString(e));
            throw new DaoException(e.getMessage(), e);
        }

    }

    //根据任务号查询日志
    public QueryRespBean<HashMap> searchLog(QueryReqBean<HashMap> queryReqBean, Date startTime, Date endTime) {
        QueryRespBean<HashMap> queryRespBean = new QueryRespBean<>();
        try {
            PageHelper.startPage(queryReqBean.getPageParameter());
            HashMap searchParams = queryReqBean.getSearchParams();
            Page<HashMap> dataList = msGkLogDao.selectLog(searchParams, startTime, endTime);
            queryRespBean.setResult(dataList);
            return queryRespBean;
        } catch (Exception e) {
            throw new DaoException(e.getMessage());
        }
    }

    //判断是否有货物在货架上
    public HashMap searchWorkbinShevels(Map map) {
        return msSslShelvesDao.searchWorkbinShevels(map);
    }


    /**
     * 同步数据
     *
     * @param map
     * @return
     */
    @Transactional
    public String doTaskInfoSynchroni(HashMap map) {
        PrintWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        JSONObject resutJSon = new JSONObject();
        Map keyMap = GetAuthKey.getKey();
        resutJSon.put("startTime", map.get("startTime"));
        resutJSon.put("endTime", map.get("endTime"));
        resutJSon.put("appId", keyMap.get("appId"));
        resutJSon.put("appCode", keyMap.get("appCode"));
        resutJSon.put("timeStamp", keyMap.get("timeStamp"));
        resutJSon.put("appKey", keyMap.get("appKey"));
        resutJSon.put("sysKey", keyMap.get("sysKey"));
        String params = resutJSon.toString();
        log.info("查询需同步数据时间参数" + resutJSon.toString());
        String urlPath = msAddressDao.findPath("WCSINFO");
        try {
            String debugModel = environment.getProperty("pathProperty.deBug");
            if ("false".equals(debugModel)) {
                String urlNameString = urlPath + "/api/wcs/api/chengfei/task";
                log.info(urlNameString + "-------------------------urlNameString");
                URL realUrl = new URL(urlNameString);
                URLConnection conn = realUrl.openConnection();
                conn.setRequestProperty("accept", "*/*");
                conn.setRequestProperty("connection", "Keep-Alive");
                conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
                conn.setRequestProperty("Accept-Charset", "utf-8");
                conn.setRequestProperty("content-type", "application/json");
                conn.setDoOutput(true);
                conn.setDoInput(true);
                out = new PrintWriter(conn.getOutputStream());
                out.print(params);
                out.flush();
                in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
                String line;
                while ((line = in.readLine()) != null) {
                    result.append(line);
                }
            }
            log.info("同步WCS操作数据集合：" + result.toString());
            return result.toString();
        } catch (Exception e) {
            log.info(ExceptionToStirng.getExceptionToString(e));
            e.printStackTrace();
            R.failed("400", e.getMessage());
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                log.info(ex.getMessage());
            }

        }
        return result.toString();
    }

    /**
     * 为保证硬件软件双系统中的信息保持一致。
     * 信息同步接口。调用wcs系统接口，
     *
     * @param timeMap
     * @return
     */
    @Transactional
    public HashMap InfoSynchroni(HashMap timeMap) {
        HashMap returnMap = new HashMap();
        try {
            String debugModel = environment.getProperty("pathProperty.deBug");
            //需要同步的数据时间段参数传入调用WCS接口，获取在该时间段中，需要同步的数据操作。
            String wcsResult = doTaskInfoSynchroni(timeMap);
            if ("false".equals(debugModel)) {
                if (wcsResult != null && wcsResult != "") {
                    //获取wcs返回的List<map>参数
                    HashMap<String, Object> wcsDatas = JSON.parseObject(wcsResult, new TypeReference<HashMap<String, Object>>() {
                    });
                    if (wcsDatas.get("data") != null) {
                        HashMap callMap = new HashMap();
                        List infoList = (List) wcsDatas.get("data");
                        //遍历所有参数集合，插入同步数据临时表格
                        for (int i = 0; i < infoList.size(); i++) {
                            HashMap infoMap = JSON.parseObject(infoList.get(i).toString(), HashMap.class);
                            log.info("infoMap", infoMap);
                            msSslShelvesDao.insertInfoSynchroni(infoMap);
                        }
                        //处理临时表格，获取操作盘编码，时间最近一次操作，进行货架数据统一。
                        msSslShelvesDao.callInfoSynchroni(callMap);
                        if (callMap.get("o_Return_Int") != null && callMap.get("o_Return_Int").equals(0)) {
                            returnMap.put("retCode", "200");
                            returnMap.put("msg", "执行成功！");
                        } else {
                            returnMap.put("retCode", "200");
                            returnMap.put("msg", callMap.get("o_Return_String"));
                        }
                    } else {
                        returnMap.put("retCode", "201");
                        returnMap.put("msg", "该时间段不存在需要同步的任务！");
                    }
                }
            }
        } catch (Exception e) {
            log.info(ExceptionToStirng.getExceptionToString(e));
            e.printStackTrace();
        } finally {
            return returnMap;
        }

    }
}
